package com.netx.ebs;
import com.netx.generics.basic.Context;
import com.netx.generics.time.TimeValue;
import com.netx.generics.time.Moment;
import com.netx.generics.time.TimeValue.MEASURE;
import com.netx.data.Database;
import com.netx.generics.io.FileSystem;


public class EbsContext extends Context {

	EbsContext() {
		super("ebs", Context.getRootContext());
		new Context("internal", this);
		// Set application-global properties:
		setProperty(Constants.EBSCTX_INIT_CALLED, false);
		setProperty(Constants.EBSCTX_APPLICATION_STATE, APPLICATION_STATE.RUNNING);
		setProperty(Constants.EBSCTX_SESSION_MANAGER, new SessionManager());
		// Set default values for basic properties:
		setProperty("charset", "UTF-8");
		setProperty("send-error-codes", true);
		setProperty("save-errors-in-database", false);
		// Rules MUST be set and applied when <context.xml> are loaded.
	}
	
	public String getAuthenticatorName() {
		return getProperty("authenticator-name").stringValue();
	}

	public String getErrorHandlerName() {
		return getProperty("error-handler").stringValue();
	}

	public boolean getSendErrorCodes() {
		return getProperty("send-error-codes").booleanValue();
	}

	public boolean getKeepSessionsOnReload() {
		return getProperty("keep-sessions-on-reload").booleanValue();
	}

	public String getSessionMode() {
		return getProperty("session-mode").stringValue();
	}

	public boolean getAllowMultipleSessions() {
		return getProperty("allow-multiple-sessions").booleanValue();
	}
	
	public TimeValue getSessionCheckDaemonPeriod() {
		return (TimeValue)getProperty("session-check-daemon-period").objectValue();
	}

	public TimeValue getNotificationCheckDaemonPeriod() {
		return (TimeValue)getProperty("notification-check-daemon-period").objectValue();
	}

	public TimeValue getNotificationKeepTime() {
		return (TimeValue)getProperty("notification-keep-time").objectValue();
	}

	public String getCharset() {
		return getProperty("charset").stringValue();
	}

	public boolean getSaveErrorsInDatabase() {
		return getProperty("save-errors-in-database").booleanValue();
	}

	public boolean getShowStackTrace() {
		return getProperty("show-stack-trace").booleanValue();
	}
	
	public Database getDatabase() {
		return (Database)getProperty("database").objectValue();
	}

	public FileSystem getApplicationRoot() {
		return (FileSystem)getProperty("application-root").objectValue();
	}

	public String getApplicationName() {
		return (String)getProperty("application-name").objectValue();
	}

	// The APPLICATION_STATE property must be internal, because it MUST
	// be changeable (to start and stop the application), but only from EbsContext.
	public APPLICATION_STATE getApplicationState() {
		return (APPLICATION_STATE)getProperty(Constants.EBSCTX_APPLICATION_STATE).objectValue();
	}

	// internal property getters and setters:
	boolean internalGetInitCalled() {
		return getProperty(Constants.EBSCTX_INIT_CALLED).booleanValue();
	}

	void internalStopApplication() {
		setProperty(Constants.EBSCTX_APPLICATION_STATE, APPLICATION_STATE.STOPPED);
	}

	void internalStartApplication() {
		setProperty(Constants.EBSCTX_APPLICATION_STATE, APPLICATION_STATE.RUNNING);
	}

	SessionManager internalGetSessionManager() {
		return (SessionManager)getProperty(Constants.EBSCTX_SESSION_MANAGER).objectValue();
	}

	void internalSetStartupTime(TimeValue startupTime) {
		setProperty(Constants.EBSCTX_STARTUP_TIME, startupTime);
		setProperty(Constants.EBSCTX_STOPPED_TIME, new Moment());
	}
	
	TimeValue internalGetExpectedStartupTime() {
		TimeValue startupTime = (TimeValue)getProperty(Constants.EBSCTX_STARTUP_TIME).objectValue();
		Moment stoppedTime = (Moment)getProperty(Constants.EBSCTX_STOPPED_TIME).objectValue();
		Moment timeElapsed = new Moment().subtract(stoppedTime);
		long timeMissing = startupTime.getAs(MEASURE.MILLISECONDS) - timeElapsed.getTimeInMilliseconds();
		if(timeMissing < 0) {
			timeMissing = 0;
		}
		return new TimeValue(timeMissing, MEASURE.MILLISECONDS);
	}
}
